home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
018
/
amigadisplay
/
intuit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
14KB
|
376 lines
/*********************************************************************\
* This file has Intuition-related stuff: menus, fonts, etc (intuit.c) *
\*********************************************************************/
#include <exec/types.h>
#include <exec/exec.h>
#include <stdio.h>
#include <libraries/diskfont.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
/* Library pointers imported from main.c */
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct DiskfontBase *DiskfontBase;
/*
* Initialise an IntuiText structure
*/
/* constants for pen colors */
#define FORE0 (0 << 2)
#define FORE1 (1 << 2)
#define FORE2 (2 << 2)
#define FORE3 (3 << 2)
#define BACK0 0
#define BACK1 1
#define BACK2 2
#define BACK3 3
static InitText(intui, text, pens, left, top) struct IntuiText *intui; char *text; SHORT pens, left, top; {
intui->FrontPen = (pens >> 2) & 3;
intui->BackPen = pens & 3;
intui->DrawMode = JAM2;
intui->LeftEdge = left;
intui->TopEdge = top;
intui->ITextFont = NULL;
intui->NextText = NULL;
intui->IText = (UBYTE *)text;
}
/*
* Menu Creation
*/
/* macro to compute size in bytes for menu with n items */
#define MenuBytes(n) (sizeof(struct Menu) + (n)*(sizeof(struct MenuItem) + sizeof(struct IntuiText)))
static struct Menu *menuList = NULL;
static AddMenu(title, size, names, init, rightify) int size, init, rightify; char *title, *names[]; {
struct Menu **menu;
struct MenuItem *items = NULL;
struct IntuiText *text = NULL;
int n, width = 0, itemLeft = 1, menuLeft = 5;
USHORT flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
if (init >= 0) {flags |= CHECKIT; itemLeft += CHECKWIDTH;}
for (menu = &menuList; *menu; menu = &((*menu)->NextMenu)) menuLeft += 90;
/* menu now points to where the next menu pointer should go */
*menu = (struct Menu *)AllocMem(MenuBytes(size), MEMF_CHIP);
if (*menu == NULL) return(TRUE); /* out of memory */
items = (struct MenuItem *)(sizeof(**menu) + (UBYTE *)*menu);
text = (struct IntuiText *)(size*sizeof(*items) + (UBYTE *)items);
InitText(text, (*menu)->MenuName = title, 0, 0, 0); /* just to measure it */
(*menu)->Width = 8 + IntuiTextLength(text);
for (n=0; n<size; n++) {
int thisWidth;
InitText(text, *names++, FORE0|BACK1, itemLeft, 1);
thisWidth = IntuiTextLength(text++);
width = max(width, thisWidth); /* max is macro; mustn't do ++ twice! */
}
text -= size;
width += 2;
if (init >= 0) width += CHECKWIDTH;
(*menu)->LeftEdge = rightify ? 630-width : menuLeft;
(*menu)->FirstItem = items;
(*menu)->NextMenu = NULL;
(*menu)->TopEdge = 0;
(*menu)->Height = 10;
(*menu)->Flags = MENUENABLED;
for (n=0; n<size; n++) {
items->NextItem = items+1;
items->LeftEdge = 0;
items->TopEdge = 11 * n;
items->Width = width;
items->Height = 10;
items->Flags = flags;
items->MutualExclude = (~(1 << n));
items->ItemFill = (APTR)text++;
items->SelectFill = NULL;
items->Command = 0;
items->SubItem = NULL;
items->NextSelect = 0;
items++;
}
(--items)->NextItem = NULL;
items -= (size-1);
if (init >= 0 && init < size) items[init].Flags |= CHECKED;
return(FALSE); /* no problems */
} /* end of AddMenu */
/* Specific menus */
static char *fileStrings[] = {"Start Capture", "Start Send", "End Capture", "Cancel Send"};
static char *baudStrings[] = {" 300", "1200", "2400", "4800", "9600"};
static char *dpyStrings[] = {"Vanilla", "SAIL"};
static char *beepStrings[] = {"Brash", "Clear", "Calm", "Eerie", "Subdued", "Silent"};
static char *wnStrings[] = {"Move to Back", "Move to Front", "Close Window"};
static InitMenus() { /* returns TRUE if unable to create them all */
return(AddMenu("File", 2, fileStrings, -1, FALSE)
|| AddMenu("Baud", 5, baudStrings, 1, FALSE)
|| AddMenu("Display", 2, dpyStrings, 1, FALSE)
|| AddMenu("Beep", 6, beepStrings, 1, FALSE)
|| AddMenu("Window", 3, wnStrings, -1, TRUE));
}
/*
* SAIL Font (weird chars in positions 0x80-0x9F)
*/
static struct TextFont *tf;
static InitSAILFont(window) struct Window *window; {
struct TextAttr ta;
ta.ta_Name = "SAIL.font";
ta.ta_YSize = 8;
ta.ta_Style = 0;
ta.ta_Flags = FPF_ROMFONT | FPF_DISKFONT |
FPF_PROPORTIONAL | FPF_DESIGNED;
tf = (struct TextFont *)OpenDiskFont(&ta);
if (tf) SetFont(window->RPort, tf);
}
InitWindowStuff(window) struct Window *window; {
if (InitMenus() || MakeRequester()) {FreeMenus(); return(TRUE);}
InitSAILFont(window);
SetMenuStrip(window, menuList);
return(FALSE); /* no problem */
}
CleanUpWindow(window) struct Window *window; {
if (tf) CloseFont(tf);
if (window) ClearMenuStrip(window);
FreeMenus();
}
static FreeMenus() {
struct MenuItem *item;
while (menuList) {
int size = 0;
struct Menu *next = menuList->NextMenu;
for (item = menuList->FirstItem; item; item = item->NextItem) size++;
FreeMem(menuList, MenuBytes(size));
menuList = next;
}
}
/*
* Function to handle file menu commands, usually via a requester
*/
FileMenu(w, item, r, s, flags) struct Window *w; int item, *flags; FILE **r, **s; {
/* called with item<0 to fix up menu item text to match current state */
switch (item) {
case 0: /* capture */
if (OpenOrCloseFile(w, r, "Capture to", "w", "Include control chars?")) *flags |= 1;
else *flags &= ~1;
break;
case 1: /* send */
if (OpenOrCloseFile(w, s, "Send", "r", "Convert LFs to CRs?")) *flags |= 2;
else *flags &= ~2;
break;
}
((struct IntuiText *)menuList->FirstItem->ItemFill)->IText =
(UBYTE *)fileStrings[*r == NULL ? 0 : 2];
((struct IntuiText *)menuList->FirstItem->NextItem->ItemFill)->IText =
(UBYTE *)fileStrings[*s == NULL ? 1 : 3];
}
/* The Requester */
static struct Requester myreq;
#define FNAMEBUFSIZE 60
static UBYTE fnamebuf[FNAMEBUFSIZE];
static struct StringInfo fname = {
fnamebuf, NULL, 0, FNAMEBUFSIZE, 0, 0, 0, 0, 0, 0, 0, 0, NULL};
/* border for requester */
#define FILREQWIDTH 400
#define FILREQHEIGHT 130
#define TEXTGAP 14
#define TEXTTOP 10+TEXTGAP*2
static SHORT reqPairs[] = {
4, 2, FILREQWIDTH-5, 2,
FILREQWIDTH-5, FILREQHEIGHT-3, 4, FILREQHEIGHT-3,
4, 2, 5, 2,
5, FILREQHEIGHT-3, FILREQWIDTH-6, FILREQHEIGHT-3,
FILREQWIDTH-6, 2 };
static SHORT textPairs[] = {0, TEXTTOP-TEXTGAP-1, 0, TEXTTOP-TEXTGAP-1};
static SHORT errorPairs[] = {0, TEXTTOP-2*TEXTGAP-1, 0, TEXTTOP-2*TEXTGAP-1};
/* border for activation gadgets */
#define OCTLAP 2
#define OCTWIDTH 100 /* tentative, adjusted based on font width */
#define OCTHEIGHT 27 /* likewise adjusted based on font height */
static SHORT gadPairs[] = {
OCTLAP*4, -OCTLAP,
OCTWIDTH-OCTLAP*4-1, -OCTLAP,
OCTWIDTH+OCTLAP*2-1, OCTLAP*2,
OCTWIDTH+OCTLAP*2-1, OCTHEIGHT-OCTLAP*2-1,
OCTWIDTH+OCTLAP*2-2, OCTLAP*2,
OCTWIDTH+OCTLAP*2-2, OCTHEIGHT-OCTLAP*2-1,
OCTWIDTH+OCTLAP*2-1, OCTHEIGHT-OCTLAP*2-1,
OCTWIDTH-OCTLAP*4-1, OCTHEIGHT+OCTLAP-1,
OCTLAP*4, OCTHEIGHT+OCTLAP-1,
-OCTLAP*2, OCTHEIGHT-OCTLAP*2-1,
-OCTLAP*2, OCTLAP*2,
-OCTLAP*2+1, OCTHEIGHT-OCTLAP*2-1,
-OCTLAP*2+1, OCTLAP*2,
-OCTLAP*2, OCTLAP*2,
OCTLAP*4, -OCTLAP };
/* border and background for yes/no gadget */
static SHORT ynBkgPairs[48];
static SHORT ynBrdPairs[] = {-2,-1, -2,3, 1,3, 1,-1, -1,-1, -1,3, 0,3, 0,-1};
static struct Border reqBorder = {0, 0, 3, 0, JAM1, 9, reqPairs, NULL};
static struct Border textBorder = {0, 0, 3, 2, JAM1, 2, textPairs, &reqBorder};
static struct Border errBorder = {0, 0, 1, 2, JAM1, 2, errorPairs, &textBorder};
static struct Border gadBorder = {0, 0, 3, 2, JAM1, 15, gadPairs, NULL};
static struct Border ynBorder = {0, 0, 1, 0, JAM1, 8, ynBrdPairs, NULL};
static struct Border ynBackground = {0, 0, 0, 2, JAM1, 24, ynBkgPairs, &ynBorder};
static struct IntuiText gadText[4], ynText[2];
static struct IntuiText reqText, errorText, optText;
static char reqTextChars[30];
static struct Gadget gadgets[5] = {
{&gadgets[1], 20,-20-OCTHEIGHT,OCTWIDTH,OCTHEIGHT,
GADGHCOMP | GRELBOTTOM, RELVERIFY | ENDGADGET, REQGADGET | BOOLGADGET,
(APTR)&gadBorder, NULL, &gadText[0], NULL, NULL, TRUE, NULL},
{&gadgets[2], -20-OCTWIDTH,-20-OCTHEIGHT,OCTWIDTH,OCTHEIGHT,
GADGHCOMP | GRELRIGHT | GRELBOTTOM, RELVERIFY | ENDGADGET, REQGADGET | BOOLGADGET,
(APTR)&gadBorder, NULL, &gadText[1], NULL, NULL, FALSE, NULL},
{&gadgets[3], 0,TEXTTOP+TEXTGAP*3/2,0,0,
GADGHCOMP, RELVERIFY, REQGADGET | BOOLGADGET,
(APTR)&ynBackground, NULL, &ynText[0], NULL, NULL, TRUE, (APTR)&gadgets[3]},
{&gadgets[4], 0,TEXTTOP+TEXTGAP*3/2,0,0,
GADGHCOMP, RELVERIFY, REQGADGET | BOOLGADGET,
(APTR)&ynBackground, NULL, &ynText[1], NULL, NULL, FALSE, (APTR)&gadgets[2]},
{NULL, FILREQWIDTH/5,TEXTTOP,FILREQWIDTH*3/5,12,
GADGHCOMP, STRINGCENTER, REQGADGET | STRGADGET,
NULL, NULL, NULL, NULL, (APTR)&fname, NULL, NULL} };
static MakeRequester() {
int n, width;
BYTE height;
SHORT *coord;
InitRequester(&myreq);
myreq.LeftEdge = (640-FILREQWIDTH)/2;
myreq.TopEdge = 8;
myreq.Width = FILREQWIDTH;
myreq.Height = FILREQHEIGHT;
myreq.ReqGadget = gadgets;
myreq.ReqBorder = &textBorder;
myreq.ReqText = &reqText;
myreq.BackFill = 2;
GetPrefs(&height, 1); /* get height of default font */
InitText(&ynText[0], "Yes", FORE1|BACK0, 4, 2);
InitText(&ynText[1], "No", FORE1|BACK0, 4, 2);
width = IntuiTextLength(&ynText[0]);
ynText[1].LeftEdge += (width-IntuiTextLength(&ynText[1])) / 2;
gadgets[2].Width = gadgets[3].Width = width += 8;
gadgets[2].Height = gadgets[3].Height = height+3;
coord = ynBkgPairs;
for (n=0; n<height+3; n++) {
*coord++ = n&1 ? width-1 : 0;
*coord++ = n;
*coord++ = n&1 ? 0 : (width-1);
*coord++ = n;
}
ynBackground.Count = (height+3)*2; /* number of pairs to draw background */
coord = ynBrdPairs-1;
for (n=0; n<ynBorder.Count; n++) {
if (*++coord >= 0) *coord += width;
if (*++coord >= 0) *coord += height;
}
InitText(&gadText[0], " CONFIRM ", FORE0|BACK1, 2, height+1);
InitText(&gadText[1], " FORGET IT ", FORE0|BACK1, 2, height+1);
InitText(&gadText[2], " ", FORE0|BACK1, 2, 1);
InitText(&gadText[3], " ", FORE0|BACK1, 2, height*2+1);
gadText[0].NextText = gadText[1].NextText = &gadText[2];
gadText[2].NextText = &gadText[3];
gadgets[1].Width = gadgets[0].Width = width = IntuiTextLength(gadText) + 4;
gadgets[1].Height = gadgets[0].Height = height = height*3 + 2;
gadgets[1].LeftEdge = -20-width;
coord = gadPairs-1;
for (n=0; n<gadBorder.Count; n++) {
if (*++coord > OCTWIDTH/2) *coord += width-OCTWIDTH;
if (*++coord > OCTHEIGHT/2) *coord += height-OCTHEIGHT;
}
InitText(&reqText, reqTextChars, FORE2|BACK3, 0, TEXTTOP - TEXTGAP);
reqText.NextText = &optText;
InitText(&optText, NULL, FORE1|BACK2, 0, gadgets[2].TopEdge + ynText[0].TopEdge);
InitText(&errorText, " Can't open file; try again ", FORE0|BACK1, 0, TEXTTOP - 2*TEXTGAP);
errorText.NextText = &reqText;
width = IntuiTextLength(&errorText);
errorPairs[0] = errorText.LeftEdge = (FILREQWIDTH-width) / 2;
errorPairs[2] = errorPairs[0] + width - 1;
return(FALSE); /* no problems */
}
static OpenOrCloseFile(w, file, label, mode, option) struct Window *w; FILE **file; char *label, *mode, *option; {
struct IntuiMessage *message;
ULONG class;
struct Gadget *gadg;
int proceed, k, opt;
if (*file != NULL) {fclose(*file); *file = NULL; return(NULL);}
sprintf(reqTextChars, " %s file: ", label);
k = IntuiTextLength(&reqText);
textPairs[0] = reqText.LeftEdge = (FILREQWIDTH-k) / 2;
textPairs[2] = textPairs[0] + k - 1;
optText.IText = (UBYTE *)option;
k = IntuiTextLength(&optText);
opt = gadgets[2].Width + 2; /* distance between Yes gadget and No gadget */
optText.LeftEdge = (FILREQWIDTH - (k + 3*opt)) / 2;
gadgets[2].LeftEdge = optText.LeftEdge + k + opt;
gadgets[3].LeftEdge = gadgets[2].LeftEdge + opt;
fnamebuf[0] = k = 0;
myreq.ReqBorder = &textBorder;
myreq.ReqText = &reqText;
gadgets[2].Flags &= ~SELECTED;
gadgets[3].Flags |= SELECTED;
gadgets[2].Activation |= TOGGLESELECT;
gadgets[3].Activation &= ~TOGGLESELECT;
for (;;) {
if (! Request(&myreq, w)) return(NULL); /* couldn't open requester */
for (proceed=TRUE; proceed; ) {
while (message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
class = message->Class;
gadg = (struct Gadget *)message->IAddress;
ReplyMsg(message);
switch (class) {
case GADGETUP:
if (gadg->Activation & ENDGADGET) {
k = gadg->GadgetID;
opt = gadgets[2].Flags & SELECTED;
}
else if (gadg->Activation & TOGGLESELECT) {
gadg->Activation &= ~TOGGLESELECT;
gadg = (struct Gadget *)gadg->UserData;
gadg->Flags &= ~SELECTED;
gadg->Activation |= TOGGLESELECT;
RefreshGadgets(&gadgets[2], w, &myreq);
}
break;
case REQCLEAR: proceed = FALSE; break;
}
}
}
/* requester came down, now check what we're supposed to do */
if (!k) return(NULL); /* user said to forget it */
if (*file = fopen(fnamebuf, mode)) return(opt); /* no problem */
/* bring requester back, this time with error message added */
myreq.ReqBorder = &errBorder;
myreq.ReqText = &errorText;
}
}